with OpenAI, WordPress, Google Sheets & Slack
工作流概述
这是一个包含32个节点的复杂工作流,主要用于自动化处理各种任务。
工作流源代码
{
"id": "AhP1Fgv0eCrh9Jxs",
"meta": {
"instanceId": "b9faf72fe0d7c3be94b3ebff0778790b50b135c336412d28fd4fca2cbbf8d1f5",
"templateCredsSetupCompleted": true
},
"name": "AI-Generated Summary Block for WordPress Posts - with OpenAI, WordPress, Google Sheets & Slack",
"tags": [],
"nodes": [
{
"id": "0733b902-6707-4548-9498-44993ed6a16c",
"name": "When clicking ‘Test workflow’",
"type": "n8n-nodes-base.manualTrigger",
"position": [
500,
-780
],
"parameters": {},
"typeVersion": 1
},
{
"id": "fa1fea27-c44d-4c8b-89ab-e7f84e91048f",
"name": "Text Classifier",
"type": "@n8n/n8n-nodes-langchain.textClassifier",
"position": [
5520,
-800
],
"parameters": {
"options": {
"systemPromptTemplate": "Analyze the provided text and classify it into one of the following categories: {categories}.
- If the text contains an 'AI Summary', classify it as \"summarized\".
- If the text does not contain an 'AI Summary', classify it as \"not_summarized\".
Follow these instructions strictly:
- Provide the result in JSON format.
- Do not include any explanations, comments, or additional text.
"
},
"inputText": "={{ $json.data }}",
"categories": {
"categories": [
{
"category": "not_summarized",
"description": "Content that does not contain an 'AI Summary'."
},
{
"category": "=summarized",
"description": "Content that contains an 'AI Summary'."
}
]
}
},
"typeVersion": 1
},
{
"id": "258d93f8-50db-4c95-8315-b7284100a426",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
5540,
-600
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"id": "",
"name": "OpenAi Connection"
}
},
"typeVersion": 1.1
},
{
"id": "7634cffa-0df8-4c11-84f4-c24cff652432",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
2060,
-780
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "1742dc9a-89b7-44f4-8ddb-5658fd34cadf",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
3660,
-820
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "44a27f03-4285-4771-a507-c55f029256e9",
"operator": {
"type": "number",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.post_id }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"disabled": true,
"position": [
500,
-360
],
"webhookId": "",
"parameters": {
"path": "4946fc26-bea4-4244-b37c-203c39537246",
"options": {},
"httpMethod": "POST",
"authentication": "headerAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "",
"name": "wp-webhook"
}
},
"typeVersion": 2
},
{
"id": "4c77eb08-e855-4a07-b76a-d5cea322fbca",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"disabled": true,
"position": [
500,
-600
],
"parameters": {
"rule": {
"interval": [
{
"field": "seconds"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "cb1dce7c-6dfb-4435-aca8-013fdac58d43",
"name": "Wordpress - Update Post",
"type": "n8n-nodes-base.httpRequest",
"position": [
7920,
-820
],
"parameters": {
"url": "=https://<your-domain.com>/wp-json/wp/v2/posts/{{ $('Loop Over Items').item.json.id }}",
"method": "POST",
"options": {},
"sendBody": true,
"authentication": "predefinedCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "=content",
"value": "={{ `${$json.message.content} ${$('Text Classifier').item.json.content.raw}` }}"
},
{
"name": "excerpt",
"value": "={{ $('Text Classifier').item.json.excerpt.rendered }}"
}
]
},
"nodeCredentialType": "wordpressApi"
},
"credentials": {
"wordpressApi": {
"id": "",
"name": ""
}
},
"typeVersion": 4.2
},
{
"id": "4aa026fd-29c3-4848-bfd1-98efba165b68",
"name": "Google Sheets - Get rows",
"type": "n8n-nodes-base.googleSheets",
"position": [
2920,
-820
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupValue": "={{ $json.id }}",
"lookupColumn": "post_id"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1uO0zaNc5UrLhtdcvETFcZGln_qij-nqpYP06n9GxJUk/edit#gid=0",
"cachedResultName": "AI-Summarized Posts"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1uO0zaNc5UrLhtdcvETFcZGln_qij-nqpYP06n9GxJUk",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1uO0zaNc5UrLhtdcvETFcZGln_qij-nqpYP06n9GxJUk/edit?usp=drivesdk",
"cachedResultName": "Template - AI Summary WordPress Posts"
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"id": "",
"name": "Google Sheets account"
}
},
"typeVersion": 4.5,
"alwaysOutputData": true
},
{
"id": "0139af9a-5afc-4ac5-9631-4d217cdbc967",
"name": "HTML to Markdown",
"type": "n8n-nodes-base.markdown",
"position": [
4700,
-800
],
"parameters": {
"html": "={{ $json.content.rendered }}",
"options": {}
},
"typeVersion": 1
},
{
"id": "3272ff54-9c8f-4003-bdf6-c16e8f4ba972",
"name": "OpenAI",
"type": "@n8n/n8n-nodes-langchain.openAi",
"onError": "continueRegularOutput",
"position": [
7060,
-820
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "GPT-4O-MINI"
},
"options": {},
"messages": {
"values": [
{
"content": "={{ $json.data }}"
},
{
"role": "system",
"content": "=You are an expert in content summarization and web-optimized writing.
Your mission is to analyze the HTML content of an article from a website focused on electric vehicles and green mobility and extract the key information.
Generate only an HTML block containing a concise summary in bullet point format, strictly following this structure:
<!-- wp:html -->
<div class=\"wp-block-group has-background\" style=\"background-color:#f8faff; border-radius:4px; padding:10px;\">
<p style=\"font-style:normal; font-weight:1000; font-size:1.1em; margin:0 0 10px 0;\">
<strong>✨ AI Summary</strong> :
</p>
<li>[Key point 1]</li>
<li>[Key point 2]</li>
<li>[Key point 3]</li>
<li>[Key point 4]</li>
</div>
<!-- /wp:html -->
<!-- wp:separator -->
<hr class=\"wp-block-separator has-alpha-channel-opacity\"/>
<!-- /wp:separator -->
## Important: Strict Guidelines to Follow
- Ensure the summary is **clear, concise, and informative**, focusing only on key points.
- **Avoid unnecessary introductions**, such as \"This article presents\" or similar phrases.
- **Output only the required HTML block**, without any additional explanations or commentary.
- The output must **start with** the `<!-- wp:html -->` tag and **end with** the closing separator tag.
- The summary must be **in the user's language**, including the phrase `\"✨ AI Summary\"`, which should also be translated accordingly.
- **Do not add** any extra text, comments, or formatting outside the specified HTML block.
## Example of a GOOD output:
<!-- wp:html -->
<div class=\"wp-block-group has-background\" style=\"background-color:#f8faff; border-radius:4px; padding:10px;\">
<p style=\"font-style:normal; font-weight:1000; font-size:1.1em; margin:0 0 10px 0;\">
<strong>✨ AI Summary</strong> :
</p>
<li>In March 2022, France had 43,700 public charging points for electric vehicles.</li>
<li>Half of the highway service areas are equipped with ultra-fast charging stations.</li>
<li>France is among the most equipped European countries, with 20% of the charging points in Europe.</li>
<li>The goal is to reach 100,000 charging stations to support future demand for electric vehicles.</li>
</div>
<!-- /wp:html -->
<!-- wp:separator -->
<hr class=\"wp-block-separator has-alpha-channel-opacity\"/>
<!-- /wp:separator -->
## Example of a BAD output:
```html
<!-- wp:html -->
<div class=\"wp-block-group has-background\" style=\"background-color:#f8faff; border-radius:4px; padding:10px;\">
<p style=\"font-style:normal; font-weight:1000; font-size:1.1em; margin:0 0 10px 0;\">
<strong>✨ AI Summary</strong> :
</p>
<li>In March 2022, France had 43,700 public charging points for electric vehicles.</li>
<li>Half of the highway service areas are equipped with ultra-fast charging stations.</li>
<li>France is among the most equipped European countries, with 20% of the charging points in Europe.</li>
<li>The goal is to reach 100,000 charging stations to support future demand for electric vehicles.</li>
</div>
<!-- /wp:html -->
```"
}
]
}
},
"credentials": {
"openAiApi": {
"id": "",
"name": "OpenAi Connection"
}
},
"retryOnFail": true,
"typeVersion": 1.8
},
{
"id": "f35a0520-9b88-4840-bdff-970a15a8d691",
"name": "Google Sheets - Add Row",
"type": "n8n-nodes-base.googleSheets",
"position": [
9680,
-820
],
"parameters": {
"columns": {
"value": {
"post_id": "={{ $json.id }}",
"summary": "={{$json.ai_summary}}",
"edit_link": "={{ $json.edit_link }}",
"post_link": "={{ $json.link }}",
"summarized_date": "={{$now}}"
},
"schema": [
{
"id": "post_id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "post_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "summary",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "summary",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "post_link",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "post_link",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "edit_link",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "edit_link",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "summarized_date",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "summarized_date",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "autoMapInputData",
"matchingColumns": [
"post_id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1uO0zaNc5UrLhtdcvETFcZGln_qij-nqpYP06n9GxJUk/edit#gid=0",
"cachedResultName": "AI-Summarized Posts"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1uO0zaNc5UrLhtdcvETFcZGln_qij-nqpYP06n9GxJUk",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1uO0zaNc5UrLhtdcvETFcZGln_qij-nqpYP06n9GxJUk/edit?usp=drivesdk",
"cachedResultName": "Template - AI Summary WordPress Posts"
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"id": "",
"name": "Google Sheets account"
}
},
"typeVersion": 4.5
},
{
"id": "57fd5aaf-4a43-458b-8842-72e3289c7dca",
"name": "Slack - Notify Channel",
"type": "n8n-nodes-base.slack",
"position": [
9700,
-540
],
"webhookId": "ab3305f2-3cb8-44f4-b2e6-fb628baf1d6d",
"parameters": {
"text": "=📄🔔 *New WordPress Post Updated with AI Summary*
The post *{{ $('Set fields - Prepare data for Gsheets & Slack').item.json.title }}* has been updated with an AI-generated summary at the top of the article.
You can view it here: {{ $('Set fields - Prepare data for Gsheets & Slack').item.json.post_link }}
• *Post ID*: {{ $('Set fields - Prepare data for Gsheets & Slack').item.json.post_id }}
• *Edit Link*: {{ $('Set fields - Prepare data for Gsheets & Slack').item.json.edit_link }}
",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C08AN5DJLCT",
"cachedResultName": "wp-posts-ai"
},
"otherOptions": {
"mrkdwn": true
},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"id": "",
"name": "slack-topic-monitoring-dtk"
}
},
"typeVersion": 2.3
},
{
"id": "29669a57-4104-4328-a834-0b07724fe245",
"name": "Set fields - From Webhook input",
"type": "n8n-nodes-base.set",
"position": [
700,
-360
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "eae4bb6e-0215-4338-9590-f4b6de6f57a4",
"name": "post_id",
"type": "string",
"value": "={{ $json.body.post_id }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "937d0f8b-a71e-47f0-95de-cdbb9599c524",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
400,
-1720
],
"parameters": {
"color": 7,
"width": 680,
"height": 1560,
"content": "## Trigger - Two Options
To use this workflow, you have two trigger options.
The default trigger is **\"When clicking 'Test workflow'\"**, allowing you to manually test the scenario.
If you want to use this workflow in production, you can choose one of the following triggers. You'll need to **select the one you prefer and enable it**.:
### Schedule Trigger
This trigger checks at regular intervals (e.g., every 5 minutes) if a new post has been published on your WordPress blog and triggers the workflow accordingly.
✅ **Easy to set up**
✅ **Automates AI summaries without manual intervention**
⚠️ If you run the workflow manually once, the AI-generated summaries will be added to Google Sheets and processed in later steps to prevent duplication.
💡 **Recommended follow-up nodes:** If you choose this trigger, the following nodes are suggested in the template:
- **`Date & Time - Subtract`**: Subtracts the scheduled interval from the current execution timestamp. For example, if the workflow runs every 5 minutes, it subtracts 5 minutes from the execution time.
- **`WordPress - Get Posts`**: Uses the output of the `Date & Time - Subtract` node as a filter to retrieve only posts published after the last execution.
### Webhook Trigger
If you're familiar with webhooks, you can set up a webhook that triggers when a new post is published.
✅ **Faster than scheduled triggers**
✅ **More event-driven**
You can implement this using either:
- A **Webhook plugin** on WordPress (not recommended due to plugin dependency).
- A **PHP function** that triggers the webhook with authentication for security.
⚠️ **Be cautious** with how the webhook is triggered—you may not want it to fire on every post edit.
💡 **Recommended follow-up nodes for this option:**
- **`Set Fields - From Webhook Input`**: Configures the fields based on the data sent to the webhook.
- **`WordPress - Get Post`**: Retrieves the post using the `post_id` received from the webhook, ensuring higher accuracy than the schedule trigger approach.
"
},
"typeVersion": 1
},
{
"id": "b42aa922-bf5d-4b09-8a05-ab88ec304dca",
"name": "Date & Time - Substract",
"type": "n8n-nodes-base.dateTime",
"position": [
720,
-600
],
"parameters": {
"options": {},
"duration": 30,
"timeUnit": "seconds",
"magnitude": "={{ $json.timestamp }}",
"operation": "subtractFromDate",
"outputFieldName": "last_execution_date"
},
"typeVersion": 2
},
{
"id": "0f6ada76-9195-4d2e-95be-86ea1c4f368a",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1220,
-1240
],
"parameters": {
"color": 7,
"width": 600,
"height": 1080,
"content": "## WordPress - Get All Posts
This node is used for the **initial/test run**. In production, you should use the WordPress node that follows the **Scheduled Trigger** or **Webhook Trigger** instead.
It retrieves all existing WordPress posts to generate an AI Summary.
### 🔹 Considerations:
- In this template, the query is **limited to 5 posts** to prevent accidental large-scale execution. This makes it easier to fix any issues.
- You can **add filters** (category, tag, date, etc.) to target only the posts for which you want an AI Summary.
- You can enable the **\"Get All Posts\"** option in the node if you want summaries for all posts—**but make sure this is intentional**.
- The **more posts** you process, the **higher the cost** in OpenAI API usage.
"
},
"typeVersion": 1
},
{
"id": "e806547f-6bd5-4251-9dad-ffb36b435d15",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1960,
-1240
],
"parameters": {
"color": 7,
"width": 620,
"height": 1080,
"content": "## Loop Over Items
Since multiple posts may be retrieved from the previous step, a **\"Loop Over Items\"** node is used to process each post individually, optimizing the execution of subsequent nodes.
### 🔹 In Production - Using the \"Schedule Trigger\"
You can continue using the **\"Loop Over Items\"** approach in production. Depending on your **publication frequency** and the **schedule interval** you've chosen, multiple posts could be retrieved in a single execution. This ensures each post is processed sequentially.
### 🔹 In Production - Using the \"Webhook Trigger\"
With a **Webhook Trigger**, the workflow typically runs for **one post at a time**, meaning the **\"Loop Over Items\"** node is not strictly necessary.
- **You can remove it** for a slightly more efficient workflow.
- **However, keeping it won’t cause any issues**—it will simply loop over one item instead of multiple.
"
},
"typeVersion": 1
},
{
"id": "1370d44f-3aaa-4b8d-96d8-94269cb084b4",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
2660,
-1240
],
"parameters": {
"color": 7,
"width": 1240,
"height": 1080,
"content": "## Google Sheets - Get Rows & IF Nodes
This step is used to **check whether a post already has an AI Summary**.
For the Google Sheets node, you can **[make a copy of this Google Sheets template](https://docs.google.com/spreadsheets/d/1uO0zaNc5UrLhtdcvETFcZGln_qij-nqpYP06n9GxJUk/)** by going to **File → Make a copy**.
### 🔹 How It Works:
1. **On the first execution**, posts retrieved from WordPress and processed for AI summarization are added to a **Google Sheet**.
2. **On subsequent executions**, when the workflow retrieves new posts, it checks if the `post_id` is already recorded in Google Sheets.
### 🔹 IF Node Logic:
- ✅ **If a row exists for the `post_id`** → The post already has an AI Summary. The workflow **skips processing** and moves to the `\"Loop Over Items\"` node.
- ❌ **If no row exists for the `post_id`** → The post **does not have an AI Summary**, so the workflow continues along the execution path that leads to AI Summary generation.
"
},
"typeVersion": 1
},
{
"id": "b500e31d-7bd6-4c4d-ba54-60a034d218e3",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
4000,
-1240
],
"parameters": {
"color": 7,
"width": 1140,
"height": 1080,
"content": "## WordPress - Get Post & HTML to Markdown Nodes
This step retrieves the WordPress post data using the `post_id` and converts the HTML content to Markdown. This ensures that the text is formatted in a **clean and structured way** before being sent to the **Text Classifier** node (which works with AI). More details about this step are provided in the next sticky note.
### 🔹 WordPress - Get Post
- The **`context=edit`** option is enabled to retrieve the **raw** post data.
- This is necessary because the post content will be **updated later in the workflow**.
### 🔹 HTML to Markdown
- Converts the retrieved HTML content into **Markdown** format.
- This makes the text **easier to process** for the LLM (Large Language Model) in the next step.
- Markdown ensures that the AI better understands the structure and formatting of the content.
"
},
"typeVersion": 1
},
{
"id": "249feb0b-6503-4eb1-88d8-c93764a77f33",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
5240,
-1240
],
"parameters": {
"color": 7,
"width": 1140,
"height": 1080,
"content": "## Text Classifier
This step **classifies posts into categories**:
- **`not_summarized`** → If the post **does not** have a summary, the following nodes execute the AI summary generation.
- **`summarized`** → If the post **already** has a summary, the workflow **skips processing**:
- The workflow moves to `\"Loop Over Items\"`.
- The `\"Done\"` branch goes to the `\"Do Nothing\"` node.
The LLM model used is **`gpt-4o-mini`**—it's efficient and cost-effective, but you can choose another model if needed.
### 🔹 Why Use a Text Classifier?
The previous node already filters posts **based on Google Sheets**, but adding this classification step makes the workflow even **more robust**:
- ✅ **Extra validation**: If a post already has an AI Summary but, for some reason, is **not listed in Google Sheets**, this step **prevents duplicate summaries**.
- ✅ **Avoids redundancy**: If a post already contains a **manual or pre-existing summary** at the top (not necessarily AI-generated), this step prevents adding an AI Summary that would be redundant.
"
},
"typeVersion": 1
},
{
"id": "ba3ef8b6-5826-4b2b-9bfc-b8f7c9645192",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
6480,
-1240
],
"parameters": {
"color": 7,
"width": 1100,
"height": 1080,
"content": "## OpenAI - Message a Model
This step sends the **Markdown-formatted post** to **GPT-4o-mini**, using a **System Prompt** to instruct the LLM to generate an AI Summary.
You can review and modify the **System Prompt** directly within this node.
### 🔹 Customization Required
To ensure optimal results, you should:
- **Specify your website's theme** in the system prompt. The default example uses **electric mobility**, but you can replace it with a more relevant theme (e.g., **\"sustainable mobility\"**, \"urban transport,\" etc.).
- **Modify the \"Good\" and \"Bad\" output examples**—since the template is pre-configured for electric mobility, make sure to adapt the examples to match your content.
### 🔹 Output Format
The model is instructed to return the summary in **HTML format**, which will be used to update the WordPress post.
💡 **Customization Tip**:
You may want to adjust the **HTML styling** to better match your WordPress theme.
Consider modifying the following elements:
- **Background color, text color, and font weight**
- **Section title** (e.g., rename `\"AI Summary\"`)
- **Padding, margins, and border styling**
- **Removing or customizing the separator**
### 🔹 Default Generated HTML
***
<!-- wp:html -->
<div class=\"wp-block-group has-background\" style=\"background-color:#f8faff; border-radius:4px; padding:10px;\">
<p style=\"font-style:normal; font-weight:1000; font-size:1.1em; margin:0 0 10px 0;\">
<strong>✨ AI Summary</strong> :
</p>
<li>[Key point 1]</li>
<li>[Key point 2]</li>
<li>[Key point 3]</li>
<li>[Key point 4]</li>
</div>
<!-- /wp:html -->
<!-- wp:separator -->
<hr class=\"wp-block-separator has-alpha-channel-opacity\"/>
<!-- /wp:separator -->
***"
},
"typeVersion": 1
},
{
"id": "80f2ccc9-3142-4e0c-9a6c-49b78baedec5",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
7660,
-1240
],
"parameters": {
"color": 7,
"width": 640,
"height": 1080,
"content": "## WordPress - Update Post
This API call updates the **WordPress post** and its **excerpt**.
**https://<your-domain.com>/wp-json/wp/v2/posts/{{ $('Loop Over Items').item.json.id }}**
### 🔹 What It Does
- **Adds the AI Summary** at the **top** of the post.
- **Updates the post excerpt** using data retrieved from the `WordPress - Get Post2` node:
- If a **manual excerpt** exists, it is **preserved**.
- If the excerpt was simply the **beginning of the article**, it remains unchanged.
- This prevents the **AI Summary from replacing the excerpt**, ensuring a **better user experience** on your blog’s article listing page.
"
},
"typeVersion": 1
},
{
"id": "45966c07-b20c-485e-96eb-5164165caf27",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
8400,
-1240
],
"parameters": {
"color": 7,
"width": 640,
"height": 1080,
"content": "## Set Fields - Prepare Data for Google Sheets & Slack
This node **sets fields** that will be used in **Google Sheets** and **Slack**.
You can **add or modify fields** as needed to fit your specific use case.
### 🔹 Default Fields in This Template:
The following fields are pre-configured:
- **`post_id`** → The WordPress post ID (`{{ $json.id }}`)
- **`title`** → The rendered title of the post (`{{ $json.title.rendered }}`)
- **`post_link`** → The direct URL to the post (`{{ $json.link }}`)
- **`edit_link`** → A direct link to edit the post in WordPress (**https://<your-domain>/wp-admin/post.php?post=`{{ $json.id }}`&action=edit**)
- **`summary`** → The AI-generated summary from the OpenAI node (`{{ $('OpenAI').item.json.message.content }}`)
- **`summary_date`** → The date and time when the AI Summary was generated and added to the post.
💡 **Customization Tip**:
- You can **add additional fields** if you want to include more data (e.g., **post category, author name, publication date**).
- This step ensures that the necessary information is properly structured before sending it to **Google Sheets** and **Slack**.
"
},
"typeVersion": 1
},
{
"id": "5e68e256-d089-4a1d-8967-99215b076a5b",
"name": "Set fields - Prepare data for Gsheets & Slack",
"type": "n8n-nodes-base.set",
"position": [
8680,
-820
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "d7104604-20f0-4a43-a9bb-6fca50e0cd04",
"name": "post_id",
"type": "string",
"value": "={{ $json.id }}"
},
{
"id": "4fd77b52-80b4-418b-af50-2af563799772",
"name": "title",
"type": "string",
"value": "={{ $json.title.rendered }}"
},
{
"id": "a7c0f1d4-3299-4fdc-8bc2-2ff5a76547d3",
"name": "post_link",
"type": "string",
"value": "={{ $json.link }}"
},
{
"id": "3c0d7efd-5db9-4e3b-8688-7c00f9691391",
"name": "edit_link",
"type": "string",
"value": "=https://<your-domain.com>/wp-admin/post.php?post={{ $json.id }}&action=edit"
},
{
"id": "aef982ed-b470-4690-b585-74d765a4b49f",
"name": "summary",
"type": "string",
"value": "={{ $('OpenAI').item.json.message.content }}"
},
{
"id": "38933eca-dad8-4949-a22b-0e35c9e5c99e",
"name": "summary_date",
"type": "string",
"value": "={{ $now }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "7ca77ff2-9e21-4e32-8d23-de3a549b4a6d",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
9140,
-1240
],
"parameters": {
"color": 7,
"width": 600,
"height": 1080,
"content": "## Google Sheets - Add Row & Slack - Notify
This step **logs the post with an AI Summary** into **Google Sheets** and **sends a notification** to Slack.
For the Google Sheets node, you can **[make a copy of this Google Sheets template](https://docs.google.com/spreadsheets/d/1uO0zaNc5UrLhtdcvETFcZGln_qij-nqpYP06n9GxJUk/)** by going to **File → Make a copy**.
---
### 🔹 Google Sheets - Add Row
This node **automatically maps the columns** in Google Sheets, meaning you **don't need to manually define each field**.
#### 🛠 **Configuration Details**
- **Google Sheets Document** → `AI Summary WordPress`
- **Sheet Name** → `AI Summarized Posts`
- **Mapping Mode** → **Auto-map columns based on field names**
- **Automatically added fields** (examples, based on your setup):
- `post_id`
- `summary`
- `post_link`
- `edit_link`
- `summary_date`
💡 **Since columns are mapped automatically, ensure the column names in Google Sheets match the field names in n8n.**
---
### 🔹 Slack - Notify
This node **sends a message to Slack** when a post has been updated with an **AI Summary**.
#### 🛠 **Configuration Details**
- **Channel** → `wp-posts-ai` (you can choose another channel)
- **Message Format** → Simple Text Message
- **Notification Text** -> *Configured inside the node* (check the \"Message Text\" field)
💡 **Best Practices**:
- 🔕 *On the first execution, consider **deactivating** this node if you have many posts to avoid excessive notifications.*
- 📢 *Consider **creating a dedicated Slack channel** for this workflow to keep AI summary updates separate from other discussions.*
"
},
"typeVersion": 1
},
{
"id": "64199b71-a5b2-46f1-a761-22b053e95640",
"name": "WordPress - Get Post2",
"type": "n8n-nodes-base.wordpress",
"position": [
4160,
-800
],
"parameters": {
"postId": "={{ $('Loop Over Items').item.json.id }}",
"options": {
"context": "edit"
},
"operation": "get"
},
"credentials": {
"wordpressApi": {
"id": "",
"name": ""
}
},
"typeVersion": 1
},
{
"id": "81f22a4b-b016-463c-a4e3-8468cab007a9",
"name": "No Operation, do nothing",
"type": "n8n-nodes-base.noOp",
"position": [
2900,
-1480
],
"parameters": {},
"typeVersion": 1
},
{
"id": "ec397ed4-2ccb-4407-a227-46ad2383e618",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
-380,
-1560
],
"parameters": {
"width": 660,
"height": 1100,
"content": "# 📝 AI-Generated Summary Block for WordPress Posts
## 🚀 What is this workflow?
This **n8n template** automates the process of adding an **AI-generated summary** at the top of your WordPress posts.
It **retrieves, processes, and updates** your posts dynamically, ensuring efficiency and flexibility without relying on a heavy WordPress plugin.
## Example of AI Summary Section

## 🔄 How It Works
1. **Triggers** → Runs on a **scheduled interval** or via a **webhook** when a new post is published.
2. **Retrieves posts** → Fetches content from WordPress and converts HTML to Markdown for AI processing.
3. **AI Summary Generation** → Uses OpenAI to create a concise summary.
4. **Post Update** → Inserts the summary at the top of the post while keeping the original excerpt intact.
5. **Data Logging & Notifications** → Saves processed posts to **Google Sheets** and notifies a **Slack channel**.
## 🎯 Why use this workflow?
✅ **No need for a WordPress plugin** → Keeps your site lightweight.
✅ **Highly flexible** → Easily connect with **Google Sheets, Slack, or other services**.
✅ **Customizable** → Adapt AI prompts, formatting, and integrations to your needs.
✅ **Smart filtering** → Ensures posts are not reprocessed unnecessarily.
💡 *Check the detailed sticky notes for setup instructions and customization options!*
"
},
"typeVersion": 1
},
{
"id": "9522e130-608c-4162-ac2e-3f67e216579e",
"name": "WordPress - Get Last Posts",
"type": "n8n-nodes-base.wordpress",
"position": [
960,
-600
],
"parameters": {
"options": {
"after": "={{ $json.last_execution_date }}",
"context": "edit"
},
"operation": "getAll"
},
"credentials": {
"wordpressApi": {
"id": "",
"name": ""
}
},
"typeVersion": 1
},
{
"id": "03e20423-7b5d-43ff-a241-bffa9b4c5172",
"name": "WordPress - Get Post1",
"type": "n8n-nodes-base.wordpress",
"position": [
960,
-360
],
"parameters": {
"postId": "={{ $json.post_id }}",
"options": {
"context": "edit"
},
"operation": "get"
},
"credentials": {
"wordpressApi": {
"id": "",
"name": ""
}
},
"typeVersion": 1
},
{
"id": "43963f56-ba75-4784-aebb-ebf72d075bfc",
"name": "WordPress - Get All Posts",
"type": "n8n-nodes-base.wordpress",
"position": [
1440,
-780
],
"parameters": {
"options": {
"order": "desc",
"context": "edit",
"orderBy": "date"
},
"operation": "getAll"
},
"credentials": {
"wordpressApi": {
"id": "",
"name": ""
}
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "8db35c46-bc7e-4198-95d5-f99b6bbc70c3",
"connections": {
"If": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
],
[
{
"node": "WordPress - Get Post2",
"type": "main",
"index": 0
}
]
]
},
"OpenAI": {
"main": [
[
{
"node": "Wordpress - Update Post",
"type": "main",
"index": 0
}
]
]
},
"Webhook": {
"main": [
[
{
"node": "Set fields - From Webhook input",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[
{
"node": "No Operation, do nothing",
"type": "main",
"index": 0
}
],
[
{
"node": "Google Sheets - Get rows",
"type": "main",
"index": 0
}
]
]
},
"Text Classifier": {
"main": [
[
{
"node": "OpenAI",
"type": "main",
"index": 0
}
],
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"HTML to Markdown": {
"main": [
[
{
"node": "Text Classifier",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Date & Time - Substract",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Text Classifier",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"WordPress - Get Post1": {
"main": [
[]
]
},
"WordPress - Get Post2": {
"main": [
[
{
"node": "HTML to Markdown",
"type": "main",
"index": 0
}
]
]
},
"Slack - Notify Channel": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Date & Time - Substract": {
"main": [
[
{
"node": "WordPress - Get Last Posts",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets - Add Row": {
"main": [
[
{
"node": "Slack - Notify Channel",
"type": "main",
"index": 0
}
]
]
},
"Wordpress - Update Post": {
"main": [
[
{
"node": "Set fields - Prepare data for Gsheets & Slack",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets - Get rows": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"WordPress - Get All Posts": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"WordPress - Get Last Posts": {
"main": [
[]
]
},
"Set fields - From Webhook input": {
"main": [
[
{
"node": "WordPress - Get Post1",
"type": "main",
"index": 0
}
]
]
},
"When clicking ‘Test workflow’": {
"main": [
[
{
"node": "WordPress - Get All Posts",
"type": "main",
"index": 0
}
]
]
},
"Set fields - Prepare data for Gsheets & Slack": {
"main": [
[
{
"node": "Google Sheets - Add Row",
"type": "main",
"index": 0
}
]
]
}
}
}
功能特点
- 自动检测新邮件
- AI智能内容分析
- 自定义分类规则
- 批量处理能力
- 详细的处理日志
技术分析
节点类型及作用
- Manualtrigger
- @N8N/N8N Nodes Langchain.Textclassifier
- @N8N/N8N Nodes Langchain.Lmchatopenai
- Splitinbatches
- If
复杂度评估
配置难度:
维护难度:
扩展性:
实施指南
前置条件
- 有效的Gmail账户
- n8n平台访问权限
- Google API凭证
- AI分类服务订阅
配置步骤
- 在n8n中导入工作流JSON文件
- 配置Gmail节点的认证信息
- 设置AI分类器的API密钥
- 自定义分类规则和标签映射
- 测试工作流执行
- 配置定时触发器(可选)
关键参数
| 参数名称 | 默认值 | 说明 |
|---|---|---|
| maxEmails | 50 | 单次处理的最大邮件数量 |
| confidenceThreshold | 0.8 | 分类置信度阈值 |
| autoLabel | true | 是否自动添加标签 |
最佳实践
优化建议
- 定期更新AI分类模型以提高准确性
- 根据邮件量调整处理批次大小
- 设置合理的分类置信度阈值
- 定期清理过期的分类规则
安全注意事项
- 妥善保管API密钥和认证信息
- 限制工作流的访问权限
- 定期审查处理日志
- 启用双因素认证保护Gmail账户
性能优化
- 使用增量处理减少重复工作
- 缓存频繁访问的数据
- 并行处理多个邮件分类任务
- 监控系统资源使用情况
故障排除
常见问题
邮件未被正确分类
检查AI分类器的置信度阈值设置,适当降低阈值或更新训练数据。
Gmail认证失败
确认Google API凭证有效且具有正确的权限范围,重新进行OAuth授权。
调试技巧
- 启用详细日志记录查看每个步骤的执行情况
- 使用测试邮件验证分类逻辑
- 检查网络连接和API服务状态
- 逐步执行工作流定位问题节点
错误处理
工作流包含以下错误处理机制:
- 网络超时自动重试(最多3次)
- API错误记录和告警
- 处理失败邮件的隔离机制
- 异常情况下的回滚操作